#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: Exponential.py 318 2011-07-22 16:32:02Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class SteveBattisonExponentialA2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Steve Battison Exponential A"
    _HTML = "y = exp((a + bx) / (c + dx))"
    coefficientDesignatorTuple = ("a", "b", "c", "d")
    function_cpp_code = 'temp = exp((coeff[0] + coeff[1] * _id[_cwo[0]+i]) / (coeff[2] + coeff[3] * _id[_cwo[0]+i]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = exp((a + b * x_in) / (c + d * x_in));\n"
        return s



class SteveBattisonExponentialB2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Steve Battison Exponential B"
    _HTML = "y = a * exp((b + cx) / (d + fx))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    function_cpp_code = 'temp = coeff[0] * exp((coeff[1] + coeff[2] * _id[_cwo[0]+i]) / (coeff[3] + coeff[4] * _id[_cwo[0]+i]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp((b + c * x_in) / (d + f * x_in));\n"
        return s



class Hoerl2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Hoerl"
    _HTML = "y = x<SUP>a</SUP> * exp(x)"
    coefficientDesignatorTuple = ("a")
    function_cpp_code = 'temp = pow(_id[_cwo[0]+i], coeff[0]) * _id[_cwo[1]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_ExpX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(x_in, a) * exp(x_in);\n"
        return s



class Hoerl_Transform2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Hoerl Transform"
    _HTML = "y = (bx + c)<SUP>a</SUP> * exp(bx + c)"
    coefficientDesignatorTuple = ("a", 'b', 'c')
    function_cpp_code = 'temp = pow(coeff[1] * _id[_cwo[0]+i] + coeff[2], coeff[0]) * exp(coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(b * x_in + c, a) * exp(b * x_in + c);\n"
        return s



class VaporPressure2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Standard Vapor Pressure"
    _HTML = "y = exp(a + (b/x) + c*ln(x))"
    coefficientDesignatorTuple = ("a", "b", "c")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = exp(coeff[0] + coeff[1] * _id[_cwo[1]+i] + coeff[2] * _id[_cwo[2]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[-1.0]), [-1.0]])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = exp(a + (b/x_in) + c*log(x_in));\n"
        return s



class SimpleExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Simple Exponential"
    _HTML = "y = a<SUP>x</SUP>"
    coefficientDesignatorTuple = ("a")
    function_cpp_code = 'temp = pow(coeff[0], _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(a, x_in);\n"
        return s



class AsymptoticExponentialA2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Asymptotic Exponential A"
    _HTML = "y = 1.0 - a<SUP>x</SUP>"
    coefficientDesignatorTuple = ("a")
    function_cpp_code = 'temp = 1.0 - pow(coeff[0], _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = 1.0 - pow(a, x_in);\n"
        return s



class AsymptoticExponentialA_Transform2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Asymptotic Exponential A Transform"
    _HTML = "y = 1.0 - a<SUP>bx + c</SUP>"
    coefficientDesignatorTuple = ("a", 'b', 'c')
    function_cpp_code = 'temp = 1.0 - pow(coeff[0], coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = 1.0 - pow(a, b * x_in + c);\n"
        return s



class AsymptoticExponentialB2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Asymptotic Exponential B"
    _HTML = "y = a * (1.0 - exp(bx))"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * (1.0 - exp(coeff[1] * _id[_cwo[0]+i]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * (1.0 - exp(b * x_in));\n"
        return s



class ScaledExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Scaled Exponential"
    _HTML = "y = a * exp(x)"
    coefficientDesignatorTuple = ("a")
    function_cpp_code = 'temp = coeff[0] * _id[_cwo[0]+i];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_ExpX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(x_in);\n"
        return s



class Stirling2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Stirling"
    _HTML = "y = a * (exp(bx) - 1.0) / b"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * (exp(coeff[1] * _id[_cwo[0]+i]) - 1.0) / coeff[1];'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * (exp(b*x_in) - 1.0) / b;\n"
        return s



class Exponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Exponential"
    _HTML = "y = a * exp(bx)"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] * _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b*x_in);\n"
        return s



class DoubleExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Double Exponential"
    _HTML = "y = a * exp(bx) + c * exp(dx)"
    coefficientDesignatorTuple = ("a", "b", 'c', 'd')
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] * _id[_cwo[0]+i]) + coeff[2] * exp(coeff[3] * _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b*x_in) + c * exp(d*x_in);\n"
        return s



class TripleExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Triple Exponential"
    _HTML = "y = a * exp(bx) + c * exp(dx) + f * exp(gx)"
    coefficientDesignatorTuple = ("a", "b", 'c', 'd', 'f', 'g')
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] * _id[_cwo[0]+i]) + coeff[2] * exp(coeff[3] * _id[_cwo[0]+i]) + coeff[4] * exp(coeff[5] * _id[_cwo[0]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b*x_in) + c * exp(d*x_in) + f * exp(g*x_in);\n"
        return s



class BrunoTorremansQuadrupleExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Bruno Torremans Quadruple Exponential"
    _HTML = "y = Offset - a * exp(-x/b) + c * exp(-x/d) + f * exp(-x/g) + h * exp(-x/i)"
    coefficientDesignatorTuple = ('R1', 'R2', 'R3', 'R4', 'T1', 'T2', 'T3', 'T4', 'Offset')
    function_cpp_code = 'temp = coeff[8] - coeff[0] * exp(-1.0 * _id[_cwo[0]+i] / coeff[4]) - coeff[1] * exp(-1.0 * _id[_cwo[0]+i] / coeff[5]) - coeff[2] * exp(-1.0 * _id[_cwo[0]+i] / coeff[6]) - coeff[3] * exp(-1.0 * _id[_cwo[0]+i] / coeff[7]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = Offset - R1*exp(-x_in/T1) - R2*exp(-x_in/T2) - R3*exp(-x_in/T3) - R4*exp(-x_in/T4);\n"
        return s



class OffsetExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Offset Exponential"
    _HTML = "y = a * exp(bx + c)"
    coefficientDesignatorTuple = ("a", "b", "c")
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] * _id[_cwo[0]+i] + coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b*x_in + c);\n"
        return s



class InvertedOffsetExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Inverted Offset Exponential"
    _HTML = "y = a * exp(b/(x+c))"
    coefficientDesignatorTuple = ("a", "b", "c")
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] / (_id[_cwo[0]+i] + coeff[2]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b/(x_in+c));\n"
        return s



class ShiftedExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Shifted Exponential"
    _HTML = "y = a * exp(x + b)"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * exp(_id[_cwo[0]+i] + coeff[1]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(x_in + b);\n"
        return s



class InvExponential2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Inverted Exponential"
    _HTML = "y = a * exp(b/x)"
    coefficientDesignatorTuple = ("a", "b")
    function_cpp_code = 'temp = coeff[0] * exp(coeff[1] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[-1.0]), [-1.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(b/x_in);\n"
        return s



class Hocket_Sherby2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = True
    RequiresAutoGeneratedInverseForms = True
    _name = "Hocket-Sherby"
    _HTML = "y = b - (b-a) * exp(-c * (x<sup>d</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d")
    function_cpp_code = 'temp = coeff[1] - (coeff[1] - coeff[0]) * exp(-1.0 * coeff[2] * pow(_id[_cwo[2]+i], coeff[3]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = b - (b-a) * exp(-1.0 * c * pow(x_in, d));\n"
        return s
